﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.ExportToRTR.CUiExportToRTRContentViewModel
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using DnProcessSimulateCommands.ExportToRTR.Resources;
using EngineeringInternalExtension;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows.Threading;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.PrivateImplementationDetails;


namespace DnProcessSimulateCommands.ExportToRTR{

public class CUiExportToRTRContentViewModel : CUiExportToRTRObservable
{
  private readonly string SGEMENT_MIN_TIME_KEY = "SegmentMinTime";
  private readonly string SGEMENT_MAX_TIME_KEY = "SegmentMaxTime";
  public const string SGEMENT_DEF_TIME_KEY = "SegmentDefaultTime";
  private CUiExportToRTRContentDataHandler _contentDataHandler;
  private Action _resetProgress;
  private Action<double, double, string> _startProgress;
  private Action _refreshStatus;
  private double m_step;
  private string m_segmentTimeValue;
  private double m_segmentValue;

  internal Dispatcher CurrentDispatcher { get; set; }

  internal CApExportToRTRStatusManager StatusManager { get; set; }

  public ObservableCollection<string> RoadMapConnectionOptions { get; private set; } = new ObservableCollection<string>();

  internal int SegmentTimeMinimum { set; get; } = 10;

  internal int SegmentTimeMaximum { set; get; } = 3000;

  internal int SegmentTimeDefault { set; get; } = 100;

  internal TxObjectList SelectedObjects
  {
    get => this._contentDataHandler.SelectedObjects;
    set
    {
      this.Set<TxObjectList>(ref this._contentDataHandler._selectedObjects, value, nameof (SelectedObjects));
      if (this._contentDataHandler.SelectedObjects != null && ((Collection<ITxObject>) this._contentDataHandler.SelectedObjects).Count != 0)
        return;
      this.StatusManager.AddIssue(CApExportToRTRStatusManager.IssueType.NoVisibleObjects);
    }
  }

  internal HashSet<ITxRoboticLocationOperation> SelectedLocations
  {
    get => this._contentDataHandler.SelectedLocations;
    set
    {
      this.Set<HashSet<ITxRoboticLocationOperation>>(ref this._contentDataHandler._selectedLocations, value, nameof (SelectedLocations));
    }
  }

  public string SegmentTimeValue
  {
    get => this.m_segmentTimeValue;
    set => this.Set<string>(ref this.m_segmentTimeValue, value, nameof (SegmentTimeValue));
  }

  internal int SegmentTimeCurrentValue
  {
    get => this._contentDataHandler.SegmentTime;
    set
    {
      this._contentDataHandler.SegmentTime = value;
      this.m_segmentValue = value == this.SegmentTimeMinimum ? 0.0 : Math.Log((double) (value - this.SegmentTimeMinimum + 1), this.m_step);
      this.SegmentTimeValue = value.ToString();
    }
  }

  public double SegmentValue
  {
    get => this.m_segmentValue;
    set
    {
      this.Set<double>(ref this.m_segmentValue, value, nameof (SegmentValue));
      this._contentDataHandler.SegmentTime = (int) Math.Round((double) this.SegmentTimeMinimum + (this.m_segmentValue + Math.Pow(this.m_step, this.m_segmentValue) - 1.0));
      this.SegmentTimeValue = this._contentDataHandler.SegmentTime.ToString();
    }
  }

  internal CUiExportToRTRContentViewModel(
    CApExportToRTRStatusManager statusManager,
    Action refreshStatus,
    Action resetProgress,
    Action<double, double, string> startProgress,
    CUiExportToRTRContentDataHandler contentDataHandler)
  {
    this._contentDataHandler = contentDataHandler;
    this._resetProgress = resetProgress;
    this._startProgress = startProgress;
    this._contentDataHandler.RefreshStatus = this._refreshStatus = refreshStatus;
    this._contentDataHandler.StatusManager = this.StatusManager = statusManager;
    this.LoadValuesFromRegistry();
    this.m_step = Math.Pow((double) (this.SegmentTimeMaximum - this.SegmentTimeMinimum + 1), 0.1);
    this.SegmentTimeCurrentValue = this.SegmentTimeDefault;
    this.RoadMapConnectionOptions.Add(ExportToRTRStringTable.TREE_ROADMAP_CONNECTION_CONNECTED_TO_ALL);
    this.RoadMapConnectionOptions.Add(ExportToRTRStringTable.TREE_ROADMAP_CONNECTION_CONNECTED_TO_NEXT);
  }

  private void LoadValuesFromRegistry()
  {
    string s1 = CApExportToRTRUtils.ReadValueFromRegistry(this.SGEMENT_MIN_TIME_KEY);
    if (!string.IsNullOrEmpty(s1))
      this.SegmentTimeMinimum = int.Parse(s1);
    string s2 = CApExportToRTRUtils.ReadValueFromRegistry(this.SGEMENT_MAX_TIME_KEY);
    if (!string.IsNullOrEmpty(s2))
      this.SegmentTimeMaximum = int.Parse(s2);
    string s3 = CApExportToRTRUtils.ReadValueFromRegistry("SegmentDefaultTime");
    if (string.IsNullOrEmpty(s3))
      return;
    this.SegmentTimeDefault = int.Parse(s3);
  }

  internal void RemoveOperationLocations(TxObjectList operations)
  {
    this._contentDataHandler.RemoveOperationLocations(operations);
    if (!this._contentDataHandler.IsValidationModified)
      return;
    Action refreshStatus = this._refreshStatus;
    if (refreshStatus == null)
      return;
    refreshStatus();
  }

  private void UpdateObjectsList()
  {
    TxObjectList directDescendants1 = TxApplication.ActiveDocument.PhysicalRoot.GetDirectDescendants((ITxTypeFilter) CApExportToRTRObjectsValidator.Filter);
    TxObjectList directDescendants2 = TxApplication.ActiveDocument.LogicalRoot.GetDirectDescendants((ITxTypeFilter) CApExportToRTRObjectsValidator.Filter);
    TxObjectList selectedObjects = new TxObjectList();
    this.AddSelectedObjects(directDescendants1, selectedObjects);
    this.AddSelectedObjects(directDescendants2, selectedObjects);
    SortedList<string, ITxObject> sortedList = new SortedList<string, ITxObject>();
    foreach (ITxObject itxObject in (Collection<ITxObject>) selectedObjects)
      sortedList.Add(TxObjectEx.GetUniqueNameForRTR(itxObject, false), itxObject);
    TxObjectList txObjectList = new TxObjectList();
    foreach (ITxObject itxObject in (IEnumerable<ITxObject>) sortedList.Values)
      ((Collection<ITxObject>) txObjectList).Add(itxObject);
    this.SelectedObjects = txObjectList;
  }

  private void AddSelectedObjects(TxObjectList objects, TxObjectList selectedObjects)
  {
    CApExportToRTRObjectsValidator objectsValidator = new CApExportToRTRObjectsValidator();
    foreach (ITxObject itxObject in (Collection<ITxObject>) objects)
    {
      if (objectsValidator.IsValidObject(itxObject, out string _))
        ((Collection<ITxObject>) selectedObjects).Add(itxObject);
    }
  }

  internal void UpdateLocationsList(TxObjectList selectedObjects)
  {
    this._contentDataHandler.UpdateLocationsList(selectedObjects, this._startProgress, this._resetProgress);
    this.CurrentDispatcher.BeginInvoke((Action) (() =>
    {
      if (this._contentDataHandler.InCreation)
        return;
      if (this._contentDataHandler.IsValidationModified)
      {
        this.UpdateLocationErrors();
      }
      else
      {
        Action resetProgress = this._resetProgress;
        if (resetProgress == null)
          return;
        resetProgress();
      }
    }), DispatcherPriority.Background);
  }

  internal void UpdateRobots()
  {
    this._contentDataHandler.UpdateRobots();
    this.CurrentDispatcher.BeginInvoke((Action) (() =>
    {
      if (this._contentDataHandler.IsValidationModified)
      {
        this.UpdateLocationErrors();
        this.UpdateObjectErrors();
      }
      else
      {
        Action resetProgress = this._resetProgress;
        if (resetProgress == null)
          return;
        resetProgress();
      }
    }), DispatcherPriority.Background);
  }

  private void UpdateLocationErrors()
  {
    HashSet<ITxRoboticLocationOperation> locationOperationSet = new HashSet<ITxRoboticLocationOperation>();
    List<ITxRoboticLocationOperation> locationOperationList = new List<ITxRoboticLocationOperation>();
    locationOperationSet.UnionWith((IEnumerable<ITxRoboticLocationOperation>) this._contentDataHandler.UnReachableLocations);
    locationOperationSet.UnionWith((IEnumerable<ITxRoboticLocationOperation>) this._contentDataHandler.UnConfiguredLocations);
    locationOperationSet.UnionWith((IEnumerable<ITxRoboticLocationOperation>) this._contentDataHandler.CollidingLocations);
    foreach (ITxRoboticLocationOperation locationOperation in locationOperationSet)
    {
      if (!this.StatusManager.ObjectHasIssues((ITxObject) locationOperation))
        locationOperationList.Add(locationOperation);
    }
    CApExportToRTRUtils.ComputeErrorsForList(this._contentDataHandler.UnReachableLocations, this.StatusManager, CApExportToRTRStatusManager.IssueType.LocationNotReachable);
    CApExportToRTRUtils.ComputeErrorsForList(this._contentDataHandler.UnConfiguredLocations, this.StatusManager, CApExportToRTRStatusManager.IssueType.LocationNoConfigurationFor);
    CApExportToRTRUtils.ComputeErrorsForList(this._contentDataHandler.CollidingLocations, this.StatusManager, CApExportToRTRStatusManager.IssueType.LocationWithCollision);
    foreach (ITxRoboticLocationOperation key in locationOperationList)
    {
      StringBuilder statusBuilder = new StringBuilder();
      CApEportToRTRStatusIssueBuilderToolTipString builder = new CApEportToRTRStatusIssueBuilderToolTipString(statusBuilder);
      CApExportToRTRLocationData dataOfLocation = this._contentDataHandler.DataOfLocations[key];
      this.StatusManager.PublishForObject((ITxObject) key, (CApExportToRTRStatusIssueBuilder) builder);
      dataOfLocation.IssueMessage = statusBuilder.ToString();
      dataOfLocation.IssueSevirity = this.StatusManager.ComputeSeverityForObject((ITxObject) key);
    }
    foreach (KeyValuePair<ITxRobot, CApExportToRTRRobotData> dataOfRobot in this._contentDataHandler.DataOfRobots)
    {
      if (!dataOfRobot.Value.IsVisible || dataOfRobot.Value.Is7Axis)
      {
        foreach (ITxOperation simulatingOperation in dataOfRobot.Value.SimulatingOperations)
          this.StatusManager.AddIssueWithScope(dataOfRobot.Value.Is7Axis ? CApExportToRTRStatusManager.IssueType.Robot7Axis : CApExportToRTRStatusManager.IssueType.RobotNotVisible, (ITxObject) simulatingOperation, (ITxObject) dataOfRobot.Key);
      }
    }
    foreach (KeyValuePair<ITxRoboticOrderedCompoundOperation, CApExportToRTROperationData> keyValuePair in this._contentDataHandler.DataOfOperation)
    {
      if (this.StatusManager.ObjectHasIssues((ITxObject) keyValuePair.Key))
      {
        StringBuilder statusBuilder = new StringBuilder();
        CApEportToRTRStatusIssueBuilderToolTipString builder = new CApEportToRTRStatusIssueBuilderToolTipString(statusBuilder);
        this.StatusManager.PublishForObject((ITxObject) keyValuePair.Key, (CApExportToRTRStatusIssueBuilder) builder);
        keyValuePair.Value.IssueMessage = statusBuilder.ToString();
        keyValuePair.Value.IssueSevirity = this.StatusManager.ComputeSeverityForObject((ITxObject) keyValuePair.Key);
      }
    }
    if (this._contentDataHandler.SelectedLocations.Count == 0)
      this.StatusManager.AddIssue(CApExportToRTRStatusManager.IssueType.OperationNoLocations);
    else
      this.StatusManager.RemoveIssue(CApExportToRTRStatusManager.IssueType.OperationNoLocations);
    Action refreshStatus = this._refreshStatus;
    if (refreshStatus == null)
      return;
    refreshStatus();
  }

  private void UpdateObjectErrors() => this.ComputeObjectErrorList();

  private void ComputeObjectErrorList()
  {
    HashSet<ITxObject> objects1 = new HashSet<ITxObject>();
    HashSet<ITxObject> objects2 = new HashSet<ITxObject>();
    HashSet<ITxObject> objects3 = new HashSet<ITxObject>();
    HashSet<ITxObject> objects4 = new HashSet<ITxObject>();
    HashSet<ITxObject> objects5 = new HashSet<ITxObject>();
    HashSet<ITxObject> objects6 = new HashSet<ITxObject>();
    foreach (KeyValuePair<ITxDevice, CApExportToRTRRobotToolData> dataOfTool in this._contentDataHandler.DataOfTools)
    {
      ITxObject key = (ITxObject) dataOfTool.Key;
      CApExportToRTRRobotToolData rtrRobotToolData = dataOfTool.Value;
      if (rtrRobotToolData.IsExternalAxis)
      {
        if (rtrRobotToolData.IsServoGun)
        {
          if (rtrRobotToolData.IsGunWithLoops)
            objects1.Add(key);
          if (!rtrRobotToolData.IsGunWithAvailableKinematicFunctions)
            objects2.Add(key);
          if (!rtrRobotToolData.IsGunWithLimits)
            objects3.Add(key);
          if (rtrRobotToolData.IsGunWithCompensationJoint)
            objects4.Add(key);
          if (rtrRobotToolData.HasExternalNonGun)
            objects5.Add(key);
        }
        else if (!rtrRobotToolData.IsRail)
          objects6.Add(key);
      }
    }
    CApExportToRTRUtils.ComputeErrorForObjects(objects1, this.StatusManager, CApExportToRTRStatusManager.IssueType.GunWithLoops);
    CApExportToRTRUtils.ComputeErrorForObjects(objects2, this.StatusManager, CApExportToRTRStatusManager.IssueType.NonValidKinematics);
    CApExportToRTRUtils.ComputeErrorForObjects(objects3, this.StatusManager, CApExportToRTRStatusManager.IssueType.GunWithNoLimits);
    CApExportToRTRUtils.ComputeErrorForObjects(objects4, this.StatusManager, CApExportToRTRStatusManager.IssueType.GunWithCompensationJoint);
    CApExportToRTRUtils.ComputeErrorForObjects(objects5, this.StatusManager, CApExportToRTRStatusManager.IssueType.GunWithUnsupportedExternal);
    CApExportToRTRUtils.ComputeErrorForObjects(objects6, this.StatusManager, CApExportToRTRStatusManager.IssueType.ExternalToolMonolithic);
    Action refreshStatus = this._refreshStatus;
    if (refreshStatus == null)
      return;
    refreshStatus();
  }

  internal void ComputeBlankedObjectsIssueList()
  {
    foreach (KeyValuePair<ITxObject, TxRobot> exportedAttachedTool in this._contentDataHandler.RTR3DData.ToBlankNotExportedAttachedTools)
    {
      CApExportToRTRStatusManager statusManager = this.StatusManager;
      ITxObject key = exportedAttachedTool.Key;
      TxObjectList objects = new TxObjectList();
      ((Collection<ITxObject>) objects).Add((ITxObject) exportedAttachedTool.Value);
      statusManager.AddIssue(CApExportToRTRStatusManager.IssueType.DeviceBlanked, key, objects);
    }
    foreach (KeyValuePair<ITxObject, TxRobot> exportedSubDevice in this._contentDataHandler.RTR3DData.ToBlankNotExportedSubDevices)
    {
      CApExportToRTRStatusManager statusManager = this.StatusManager;
      ITxObject key = exportedSubDevice.Key;
      TxObjectList objects = new TxObjectList();
      ((Collection<ITxObject>) objects).Add((ITxObject) exportedSubDevice.Value);
      statusManager.AddIssue(CApExportToRTRStatusManager.IssueType.SubDevicesBlanked, key, objects);
    }
  }

  internal void ComputeNoCollisionForRobotsIssueList()
  {
    foreach (TxRobot key in this._contentDataHandler.RTR3DData.RobotObjectsToExport.Keys)
    {
      if (!this._contentDataHandler.CollisionSetsData.ContainsKey((ITxRobot) key))
        this.StatusManager.AddIssue(CApExportToRTRStatusManager.IssueType.NoCollisionSetForRobot, (ITxObject) key);
    }
  }

  internal static bool AllowedOpertionType(ITxObject operation)
  {
    bool flag = true;
    if (!TxFeatureManager.CheckFeature("RTR_EXPORT_MORE_TYPES"))
    {
      switch (operation)
      {
        case ITxConcurrentRoboticOperation _:
        case ITxContinuousOperation _:
        case TxRoboticSeamOperation _:
          flag = false;
          break;
      }
    }
    return flag;
  }

  internal static ITxTypeFilter GetSupportedOperationFilter()
  {
    Type[] typeArray1 = new Type[2]
    {
      typeof (ITxRoboticOperation),
      typeof (ITxCompoundOperation)
    };
    Type[] typeArray2 = new Type[2]
    {
      typeof (ITxRoboticLocationOperation),
      typeof (ITxConcurrentRoboticOperation)
    };
    if (!TxFeatureManager.CheckFeature("RTR_EXPORT_MORE_TYPES"))
      typeArray2 = new Type[4]
      {
        typeof (ITxRoboticLocationOperation),
        typeof (ITxConcurrentRoboticOperation),
        typeof (ITxContinuousOperation),
        typeof (TxRoboticSeamOperation)
      };
    return (ITxTypeFilter) new TxTypeFilter(typeArray1, typeArray2);
  }

  internal void Init(List<ITxOperation> selectedOperations)
  {
    TxObjectList selection = (TxObjectList) null;
    if (selectedOperations.Count == 0)
    {
      selection = TxApplication.ActiveDocument.Selection.GetFilteredItems(CUiExportToRTRContentViewModel.GetSupportedOperationFilter());
    }
    else
    {
      selection = new TxObjectList(selectedOperations.Count);
      selectedOperations.ForEach((Action<ITxOperation>) (operation => ((Collection<ITxObject>) selection).Add((ITxObject) operation)));
    }
    this.UpdateObjectsList();
    this.UpdateLocationsList(CUiExportToRTRContentDataHandler.ComputeOperationsFromSelection<ITxRoboticOrderedCompoundOperation>(selection));
    this.UpdateRobots();
    this.Update3DData();
    this.UpdateCollisionSets();
  }

  private void Update3DData()
  {
    this._contentDataHandler.Update3DData();
    this.CurrentDispatcher.BeginInvoke((Action) (() => this.ComputeBlankedObjectsIssueList()), DispatcherPriority.Background);
  }

  private void UpdateCollisionSets()
  {
    this._contentDataHandler.UpdateCollisionSets();
    this.CurrentDispatcher.BeginInvoke((Action) (() => this.ComputeNoCollisionForRobotsIssueList()), DispatcherPriority.Background);
  }

  internal IApExportToRTROperationData DataOf(ITxRoboticOperation operation)
  {
    IApExportToRTROperationData rtrOperationData = (IApExportToRTROperationData) null;
    switch (operation)
    {
      case ITxRoboticLocationOperation currentLocationOperation:
        rtrOperationData = (IApExportToRTROperationData) this._contentDataHandler.ComputeLocationData(currentLocationOperation);
        break;
      case ITxRoboticOrderedCompoundOperation currentOperation:
        rtrOperationData = (IApExportToRTROperationData) this._contentDataHandler.ComputeOperationData(currentOperation);
        break;
    }
    return rtrOperationData;
  }
}
}
